import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * First Boss - Dr. Wily from Mega Man 2
 */
public class Wily  extends Mover implements Runnable
{
    private GreenfootImage[] wilyMove;
    private GreenfootImage wilyShoot;
    private retroWorld theWorld;
    private int walkCounter;
    private int vSpeed;
    private int acceleration;
    private int halfImg;
    private int halfImgWidth;
    private double moveAmount;
    private boolean invincible;
    private int hitPoints = 10;
    
    private boolean alive;
    
    WavPlayer soundBite;
    WavPlayer music;
    
    Simon simon;
    Health health;
    BossHealth healthBar;
    
    private volatile Thread t;
    
    public Wily()
    {
        wilyMove = new GreenfootImage[2];
        
        alive = true;
        invincible = false;
       
        walkCounter = 0;
        moveAmount = -1.0;
        vSpeed = 0; //Current falling speed
        acceleration = 1; //Falling speed
        halfImg = getImage().getHeight()/2;
        halfImgWidth = getImage().getWidth()/2;
        
        wilyMove[0] = new GreenfootImage("wily1.png");
        wilyMove[1] = new GreenfootImage("wily2.png");
        wilyShoot = new GreenfootImage("wilyShoot.png");
        
        healthBar = new BossHealth(hitPoints);
        
        soundBite = new WavPlayer();
        soundBite.open("face.wav");
        soundBite.setLoops(1);
        soundBite.play();
        
        music = new WavPlayer();
        music.open("28_Sigma_Battle_01.wav");
        music.setLoops(-1);
        music.play();
    }
    
    public void run()
    {
        while(alive)
        {
            if (alive)
                move(moveAmount);
            if (alive)
                fall();
            if (alive)
                cycleImage();
            if (alive)
                checkCollision();
            
            if (alive)
                shoot();
            
            //Move back if he hits the right side of the screen
            //And can be hit again
            if (alive)
                if (getX() > (theWorld.worldWidth - 50))
                {
                    moveAmount = -moveAmount;
                    invincible = false;
                }
            
            try {
                t.sleep(20);
            } catch (InterruptedException e) {}
        }
    }
    
    public void addedToWorld(World world)
    {
        theWorld = (retroWorld)world;
        simon = theWorld.getSimon();
        health = theWorld.getHealth();
   
        theWorld.addObject(healthBar, (theWorld.worldWidth - 50), (theWorld.worldHeight - 300));
        t = new Thread(this);
        t.start();
    }
    
    private void cycleImage()
    {
        if (getX() % 10 == 0)
        {
            setImage(wilyMove[walkCounter % 2]);
            walkCounter++;
        }
    }
    
    private synchronized void checkCollision()
    {
        if (intersects(simon))
        {
            if (simon.isCurrentlyWhipping()){
                if (!invincible)
                {
                    moveAmount = -moveAmount;
                    takeHit();
                    invincible = true;
                }
                return;
            }
            else if (simon.isCurrentlyWhipping() == false){
                health.takeDamage();
               
            }
        }
    }
    
    public void removeFromWorld()
    {
        try {
            
        music.stop();
        music.close();
        soundBite.open("bitchin.wav");
        soundBite.setLoops(1);
        soundBite.play();
        t.sleep(1000);       
        theWorld.addObject(new Explosion(), getX(), getY());
        theWorld.addObject(new Chris(), theWorld.worldWidth - 100, getY());
        t=null;
        theWorld.removeObject(this);
        alive=false;
        
        } catch (InterruptedException e) {}
    }
    
    private void fall()
    {
        vSpeed = vSpeed + acceleration;
        
        //detect collision with ground pixel by pixel
        for (int i = 0; i <= vSpeed; i++)
        {
            if (theWorld.isGround(getX(), getY() + halfImg + i))
            {
                vSpeed = 0;
                setLocation(getX(), getY() + i);
            }

        }
        
        setLocation (getX(), (getY() + vSpeed));
    }   
    
    /** Take hit when whipped by Simon
     * 
     */
    private void takeHit()
    {
        healthBar.takeDamage();
        hitPoints--;
        if (hitPoints <= 0)
            removeFromWorld();
    }
    
    /** Attack - shoot a bullet at random times
     * 
     */
    private void shoot()
    {
        //Randomly shoot a bullet every so often
        if (Greenfoot.getRandomNumber(50) == 0)
        {
            theWorld.addObject(new Bullet(), (getX() - halfImgWidth + 20), (getY() + 70));
            setImage(wilyShoot);
        }
    }
}
